// Connect.cpp : Implementation of CConnect
#include "stdafx.h"
#include "AddIn.h"
#include "Connect.h"

#include "UtGenerator.h"
#include "TestRunnerWnd.h"

extern CAddInModule _AtlModule;

#ifdef _VS2008
#define CONNECT L"Connect2008"
#else
#define CONNECT L"Connect"
#endif

// CConnect
STDMETHODIMP CConnect::OnConnection(IDispatch *pApplication, ext_ConnectMode ConnectMode, IDispatch *pAddInInst, SAFEARRAY ** /*custom*/ )
{
	pApplication->QueryInterface(__uuidof(EnvDTE80::DTE2), (LPVOID*)&m_pDTE);
	pAddInInst->QueryInterface(__uuidof(EnvDTE::AddIn), (LPVOID*)&m_pAddInInstance);
	if(ConnectMode == ext_cm_AfterStartup)
	{
		Initialize();
	}

	return S_OK;
}

STDMETHODIMP CConnect::OnDisconnection(ext_DisconnectMode /*RemoveMode*/, SAFEARRAY ** /*custom*/ )
{
	UnInitialize();
	m_pDTE = NULL;
	m_pAddInInstance = NULL;
	return S_OK;
}

STDMETHODIMP CConnect::OnAddInsUpdate (SAFEARRAY ** /*custom*/ )
{
	return S_OK;
}

STDMETHODIMP CConnect::OnStartupComplete (SAFEARRAY ** /*custom*/ )
{
	Initialize();
	return S_OK;
}

STDMETHODIMP CConnect::OnBeginShutdown (SAFEARRAY ** /*custom*/ )
{
	UnInitialize();
	return S_OK;
}

STDMETHODIMP CConnect::QueryStatus(BSTR bstrCmdName, EnvDTE::vsCommandStatusTextWanted NeededText, EnvDTE::vsCommandStatus *pStatusOption, VARIANT * pvarCommandText)
{
	pvarCommandText;

	if(NeededText == EnvDTE::vsCommandStatusTextWantedNone)
	{
	  if(!_wcsicmp(bstrCmdName, L"Cput." CONNECT L".Cput_1_3"))
	  {
		  EnvDTE::vsIDEMode eIdeMode;
		  if (SUCCEEDED(m_pDTE->get_Mode(&eIdeMode)) && (eIdeMode == EnvDTE::vsIDEModeDesign))
			*pStatusOption = (EnvDTE::vsCommandStatus)(EnvDTE::vsCommandStatusEnabled+EnvDTE::vsCommandStatusSupported);
		  else
			*pStatusOption = (EnvDTE::vsCommandStatus)(EnvDTE::vsCommandStatusSupported);

	  }
	  else if (!_wcsicmp(bstrCmdName, L"Cput." CONNECT L".TestRunner_1_3"))
	  {
		  *pStatusOption = (EnvDTE::vsCommandStatus)(EnvDTE::vsCommandStatusEnabled+EnvDTE::vsCommandStatusSupported);
	  }
  }
	return S_OK;
}

STDMETHODIMP CConnect::Exec(BSTR bstrCmdName, EnvDTE::vsCommandExecOption ExecuteOption, VARIANT * /*pvarVariantIn*/, VARIANT * /*pvarVariantOut*/, VARIANT_BOOL *pvbHandled)
{
	*pvbHandled = VARIANT_FALSE;
	if(ExecuteOption == EnvDTE::vsCommandExecOptionDoDefault)
	{
		if (!_wcsicmp(bstrCmdName, L"Cput." CONNECT L".Cput_1_3"))
		{
			m_csActivityMediator.TestWizard();
			*pvbHandled = VARIANT_TRUE;
		} else if (!_wcsicmp(bstrCmdName, L"Cput." CONNECT L".TestRunner_1_3"))
		{
			m_csActivityMediator.ShowTestRunnerWnd();
			*pvbHandled = VARIANT_TRUE;
		} 
	}
	return S_OK;
}


void CConnect::Initialize()
{
	if (m_bIsInitialized == FALSE)
	{
		m_bIsInitialized = TRUE;
		CreateButtons();
		m_csActivityMediator.Init(m_pDTE, m_pAddInInstance);
	}
}

void CConnect::UnInitialize()
{
	if (m_bIsInitialized)
	{
		RemoveButtons();
		m_csActivityMediator.Dispose();
		m_bIsInitialized = FALSE;
	}
}

BOOL CConnect::GetTestSubMenu(CommandBarControls * pMenuBarControls, CommandBarControl ** ppTestCommandBarControl )
{
	if ((pMenuBarControls) &&
		(ppTestCommandBarControl))
	{
		*ppTestCommandBarControl = NULL;
		
		CComVariant vtTest(L"Test");
		CComVariant vtBackup(L"Tools"); //not all Visual studio have the Test submenu so for those one the Tools submenu is used
		
		long nLocaleID = 0;
		if (SUCCEEDED(m_pDTE->get_LocaleID(&nLocaleID)))
		{
			switch(PRIMARYLANGID(nLocaleID))
			{
			//case LANG_ENGLISH: break;
				
			case LANG_FRENCH:
				vtTest = L"Test";
				vtBackup = L"Outils";
				break;
			case LANG_GERMAN:
				vtTest = L"Testen";
				vtBackup = L"Extras";
				break;
			case LANG_SPANISH:
				vtTest = L"Prueba";
				vtBackup = L"Herramientas";
				break;
			case LANG_ITALIAN:
				vtTest = L"Prova";
				vtBackup = L"Strumenti";
				break;
				//if you want to support more localize version put your code here
			}
		}

		CComVariant vt(0);
		if (SUCCEEDED(pMenuBarControls->get_Item(vtTest, ppTestCommandBarControl)))
		{	//
			return TRUE;
		}
		else if (SUCCEEDED(pMenuBarControls->get_Item(vtBackup, ppTestCommandBarControl)))
		{	
			return TRUE;
		}
	}

	return FALSE;
}

void CConnect::CreateButtons()
{
	IDispatchPtr spDisp;
	CComQIPtr<EnvDTE::Commands> spCommands;
	CComQIPtr<EnvDTE80::Commands2> spCommands2;
	CComQIPtr<_CommandBars> spCommandBars;
	CComPtr<CommandBarControl> spCommandBarControl;
	
	CComPtr<CommandBar> spMenuBarCommandBar;
	CComPtr<CommandBarControls> spMenuBarControls;
	CComPtr<CommandBarControl> spTestCommandBarControl;
	CComQIPtr<CommandBarPopup> spTestPopup;
	CComQIPtr<CommandBar> spTestCommandBar;

	if (SUCCEEDED(m_pDTE->get_CommandBars(&spDisp)) &&
		(spCommandBars = spDisp) &&
		SUCCEEDED(spCommandBars->get_Item(CComVariant(L"MenuBar"), &spMenuBarCommandBar)) &&
		(spMenuBarCommandBar) &&
		SUCCEEDED(spMenuBarCommandBar->get_Controls(&spMenuBarControls)) &&
		GetTestSubMenu(spMenuBarControls, &spTestCommandBarControl) &&
		(spTestPopup = spTestCommandBarControl) &&
		SUCCEEDED(spTestPopup->get_CommandBar(&spTestCommandBar)))
	{
		if (SUCCEEDED(m_pDTE->get_Commands(&spCommands)) &&
			(spCommands2 = spCommands) &&
			SUCCEEDED(spCommands2->AddNamedCommand2(m_pAddInInstance, 
				CComBSTR(L"Cput_1_3"), CComBSTR(L"New C++ Test..."), CComBSTR(L""), 
				VARIANT_TRUE, CComVariant(583),
				NULL, 
				EnvDTE::vsCommandStatusSupported+EnvDTE::vsCommandStatusEnabled, 
				EnvDTE80::vsCommandStylePictAndText, 
				EnvDTE80::vsCommandControlTypeButton, &m_spNewTestCommand)) &&

			SUCCEEDED(spCommands2->AddNamedCommand2(m_pAddInInstance, 
				CComBSTR(L"TestRunner_1_3"), CComBSTR(L"Test Runner Window"), CComBSTR(L""), 
				VARIANT_TRUE, CComVariant(533), NULL, 
				EnvDTE::vsCommandStatusSupported+EnvDTE::vsCommandStatusEnabled, 
				EnvDTE80::vsCommandStylePictAndText, 
				EnvDTE80::vsCommandControlTypeButton, &m_spTestRunnerCommand))
			)
		{
			m_spNewTestCommand->AddControl(spTestCommandBar, 1, &spDisp);
			m_spTestRunnerCommand->AddControl(spTestCommandBar, 2, &spDisp);
		}
		
	}
}

void CConnect::RemoveButtons()
{
	if (m_spNewTestCommand)
	{
		m_spNewTestCommand->Delete();
		m_spNewTestCommand = NULL;
	}

	if (m_spTestRunnerCommand)
	{
		m_spTestRunnerCommand->Delete();
		m_spTestRunnerCommand = NULL;
	}
}